package com.rookie.im.learn.io.mq.config;

import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

@Component
@Configurable
public class FanoutRabbitConfig implements BeanPostProcessor {

    /**
     * 使用RabbitAdmin绑定队列,自动创建不存在的队列, 防止生产者未启动,导致生产者启动异常
     */
    @Bean
    public RabbitAdmin rabbitAdmin(ConnectionFactory connectionFactory) {
        RabbitAdmin admin = new RabbitAdmin(connectionFactory);
        admin.setAutoStartup(true);
        return admin;
    }

    @Bean
    public Queue fanoutExchangeQueueA() {
        return new Queue(RabbitMQConfig.RABBITMQ_DEMO_FANOUT_EXCHANGE_QUEUE_TOPIC_A, true, false, false);
    }
    @Bean
    public Queue fanoutExchangeQueueB() {
        return new Queue(RabbitMQConfig.RABBITMQ_DEMO_FANOUT_EXCHANGE_QUEUE_TOPIC_B, true, false, false);
    }

    @Bean
    public FanoutExchange rabbitmqDemoFanoutExchange() {
        return new FanoutExchange(RabbitMQConfig.RABBITMQ_DEMO_FANOUT_EXCHANGE_DEMO_NAME,true, false);
    }

    @Bean
    public Binding bindFanoutA() {
        //队列A绑定到FanoutExchange交换机
        return BindingBuilder.bind(fanoutExchangeQueueA()).to(rabbitmqDemoFanoutExchange());
    }

    @Bean
    public Binding bindFanoutB() {
        //队列B绑定到FanoutExchange交换机
        return BindingBuilder.bind(fanoutExchangeQueueB()).to(rabbitmqDemoFanoutExchange());
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (bean instanceof RabbitAdmin) {
            RabbitAdmin rabbitAdmin = (RabbitAdmin) bean;
            rabbitAdmin.declareExchange(rabbitmqDemoFanoutExchange());
            rabbitAdmin.declareBinding(bindFanoutA());
            rabbitAdmin.declareBinding(bindFanoutB());
        }
        return bean;
    }
}
